﻿ 
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace ZK.Pack
{
    public class SerialPortScanner 
    {

        public SerialPortScanner(string portName,int baudRate)
        {
            this.portName = portName;
            this.baudRate = baudRate;
            port.PortName = portName;
            port.BaudRate = baudRate;
        }

        protected SerialPort port = new SerialPort();
        public int baudRate;
        //private bool isopen = false;
      
        private string portName;
  
        public int BaudRate
        {
            get
            {
                return this.baudRate;
            }
        }

        public bool IsOpen
        {
            get
            { 
                return this.port.IsOpen;
            }
            
        }

        
        public string PortName
        {
            get
            {
                return this.portName;
            }
        }

 
    
        public event EventHandler EventHandlerReceived;


        public virtual void Open()
        {
            try
            {
                if (this.port.IsOpen)
                {
                    this.port.Close();
                    Thread.Sleep(100);
                }
               

                this.port.DataReceived += new SerialDataReceivedEventHandler(this.OnDataReceived);
                this.port.ErrorReceived += new SerialErrorReceivedEventHandler(this.OnErrorReceived);
                this.port.Open();

            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("打开{0}端口异常:{1}", this.portName,ex.Message));
            }
        }



        public virtual void Close()
        {
            try
            {
               
                if (this.port.IsOpen)
                {
                    this.port.DataReceived -= new SerialDataReceivedEventHandler(this.OnDataReceived);
                    this.port.ErrorReceived -= new SerialErrorReceivedEventHandler(this.OnErrorReceived);
                    this.port.DiscardInBuffer();
                    Thread.Sleep(100);
                    this.port.Close();
                }
            }
            
            catch (Exception ex)
            {
                throw new Exception(string.Format("关闭{0}端口异常:{1}", this.port.PortName, ex.Message));
            }
        }


        protected virtual void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (EventHandlerReceived != null)
            {
                EventHandlerReceived(sender, null);
            }
        }


        private void OnErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            SerialError eventType = e.EventType;
            string str = "";
            switch (eventType)
            {
                case SerialError.RXOver:
                    {
                        str = "发生输入缓冲区溢出。输入缓冲区空间不足，或在文件尾 (EOF) 字符之后接收到字符。";
                        break;
                    }
                case SerialError.Overrun:
                    {
                        str = "发生字符缓冲区溢出。下一个字符将丢失。";
                        break;
                    }
                case SerialError.RXOver | SerialError.Overrun:
                    {
                        str = "未知错误。";
                        break;
                    }
                case SerialError.RXParity:
                    {
                        str = "硬件检测到奇偶校验错误。";
                        break;
                    }
                default:
                    {
                        if (eventType == SerialError.Frame)
                        {
                            str = "硬件检测到一个组帧错误。";
                            break;
                        }
                        else if (eventType == SerialError.TXFull)
                        {
                            str = "应用程序尝试传输一个字符，但是输出缓冲区已满。";
                            break;
                        }
                        else
                        {
                            goto case SerialError.RXOver | SerialError.Overrun;
                        }
                    }
            }

            
        }
    }
}
